package fb

import (
	"encoding/json"
	"fmt"
	"github.com/go-resty/resty/v2"
	"github.com/zeromicro/go-zero/core/logx"
	"navi-mumbai/common/xerr"
	"net/http"
	"time"
)

const debugTokenURI = "debug_token"

var logger = logx.WithDuration(time.Second)

type VerifyReq struct {
	FbToken      string `json:"fbToken"`
	ClientId     string `json:"clientId"`
	ClientSecret string `json:"clientSecret"`
}

type GetFbUserInfoReq struct {
	UserId       string `json:"userId"`
	ClientId     string `json:"clientId"`
	ClientSecret string `json:"clientSecret"`
}

type VerifyResultData struct {
	AppId               string   `json:"app_id"`
	Type                string   `json:"type"`
	Application         string   `json:"application"`
	DataAccessExpiresAt int64    `json:"data_access_expires_at"`
	ExpiresAt           int64    `json:"expires_at"`
	IsValid             bool     `json:"is_valid"`
	IssuedAt            int64    `json:"issued_at"`
	Scopes              []string `json:"scopes"`
	UserId              string   `json:"user_id"`
}

type GetFbUserInfoData struct {
	Id      string `json:"id"`
	Name    string `json:"name"`
	Email   string `json:"email"`
	Picture struct {
		Data struct {
			Height       int64  `json:"height"`
			IsSilhouette bool   `json:"is_silhouette"`
			Url          string `json:"url"`
			Width        int64  `json:"width"`
		} `json:"data"`
	} `json:"picture"`
}

type VerifyResultResp struct {
	Code int              `json:"code"`
	Data VerifyResultData `json:"data"`
}

type VerifyResult struct {
	Data VerifyResultData `json:"data"`
}

type GetFbUserInfoResp struct {
	Code int               `json:"code"`
	Data GetFbUserInfoData `json:"data"`
}

func (r *HttpClient) VerifyToken(req *VerifyReq) (resp *VerifyResultResp, err error) {
	resp = &VerifyResultResp{}
	rsp := &resty.Response{}

	rsp, err = r.cli.R().SetHeader("Accept", "application/json").SetQueryParams(map[string]string{
		"input_token":  req.FbToken,
		"access_token": fmt.Sprintf("%s|%s", req.ClientId, req.ClientSecret),
	}).Get(r.Host + debugTokenURI)

	if rsp == nil {
		logger.Infof("【FaceBook】 no result return ")
		err = xerr.NewGrpcErrCodeMsg(xerr.ThirdPartRequestError, "no result return")
		return
	}

	logger.Infof("【FaceBook】  rsp %s ", rsp.String())
	if err != nil {
		logger.Infof("【FaceBook】 error %s ", err.Error())
		return
	}
	if rsp.IsError() {
		logger.Infof("【FaceBook】 status %s rsp %s ", rsp.Status(), rsp.String())
		err = xerr.NewGrpcErrCodeMsg(xerr.ThirdPartRequestError, rsp.Status())
		return
	}

	fbRes := &VerifyResult{}
	err = json.Unmarshal(rsp.Body(), fbRes)
	if err != nil {
		logger.Infof("【FaceBook】 Unmarshal data error %s ", err.Error())
		err = xerr.NewGrpcErrCodeMsg(xerr.ThirdPartRequestError, err.Error())
		return
	}
	resp.Data = fbRes.Data
	resp.Code = http.StatusOK
	return
}

func (r *HttpClient) GetFbUserInfo(req *GetFbUserInfoReq) (resp *GetFbUserInfoResp, err error) {
	resp = &GetFbUserInfoResp{}
	var rsp *resty.Response

	rsp, err = r.cli.R().SetHeader("Accept", "application/json").SetQueryParams(map[string]string{
		"fields":       "id,name,email,picture",
		"access_token": req.ClientId + "|" + req.ClientSecret,
	}).Get(r.Host + req.UserId)

	logger.Infof("【FaceBook】 GetFbUserInfo rsp %s ", rsp.String())
	if err != nil {
		logger.Infof("【FaceBook】 error %s ", err.Error())
		return
	}
	if rsp.IsError() {
		logger.Infof("【FaceBook】 GetFbUserInfo status %s rsp %s ", rsp.Status(), rsp.String())
		err = xerr.NewGrpcErrCodeMsg(xerr.ThirdPartRequestError, rsp.Status())
		return
	}

	err = json.Unmarshal(rsp.Body(), &resp.Data)
	if err != nil {
		logger.Infof("【FaceBook】 Unmarshal data error %s ", err.Error())
		err = xerr.NewGrpcErrCodeMsg(xerr.ThirdPartRequestError, err.Error())
		return
	}
	resp.Code = http.StatusOK

	return
}
